package uicgas.pump.gui.impl;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.EmptyBorder;

import uicgas.pump.PumpLogic;
import uicgas.pump.PumpStateChangeNotifiable;
import uicgas.pump.device.PhysicalPump.GasolineGrade;

public class PumpGui extends JFrame implements PumpStateChangeNotifiable
{
	private static final long serialVersionUID = -4840628929075228133L;

	private final PumpLogic pumpLogic;

	private JPanel contentPane;
	private JLabel labelOne;
	private JLabel labelTwo;
	private JLabel labelThree;

	private JButton callForAssistanceButton;
	private JButton retryButton;

	private Font smallFont;
	private Font largeFont;
	//	private JLabel assistanceLabel;

	private JRadioButton RegularGradeRadioButton;
	private JRadioButton midGradeRadioButton;
	private JRadioButton premiumGradeRadioButton;
	private JButton needReceiptButton_Yes;
	private JButton needReceiptButton_No;

	/**
	 * Create the frame.
	 */
	public PumpGui(final PumpLogic pumpLogic)
	{
		this.pumpLogic = pumpLogic;

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		largeFont = new Font("SimSun-ExtB", Font.BOLD, 23);

		initialCallForAssistanceButton();

		initialLabels();

		initialRetryButton();

		initialGradeButtons();

		initialNeedReceiptButtons();

		setToWelcomScreen();
	}

	private void initialGradeButtons()
	{
		ActionListener actionListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				String text = ((JRadioButton) e.getSource()).getText();
				pumpLogic.changeGrade(GasolineGrade.valueOf(text));
			}
		};

		ButtonGroup gradeButtonGroup = new ButtonGroup();
		RegularGradeRadioButton = new JRadioButton(
				GasolineGrade.Regular.toString());
		RegularGradeRadioButton.addActionListener(actionListener);
		RegularGradeRadioButton.setBounds(80, 136, 90, 23);
		gradeButtonGroup.add(RegularGradeRadioButton);
		contentPane.add(RegularGradeRadioButton);
		RegularGradeRadioButton.setSelected(true);

		midGradeRadioButton = new JRadioButton(
				GasolineGrade.Midgrade.toString());
		midGradeRadioButton.setBounds(172, 136, 90, 23);
		midGradeRadioButton.addActionListener(actionListener);
		gradeButtonGroup.add(midGradeRadioButton);
		contentPane.add(midGradeRadioButton);

		premiumGradeRadioButton = new JRadioButton(
				GasolineGrade.Premium.toString());
		premiumGradeRadioButton.setBounds(264, 136, 90, 23);
		premiumGradeRadioButton.addActionListener(actionListener);
		gradeButtonGroup.add(premiumGradeRadioButton);
		contentPane.add(premiumGradeRadioButton);

		setGradeButtonsVisible(false);
	}

	private void initialNeedReceiptButtons()
	{
		ActionListener actionListener = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				setNeedReceiptButtonsVisible(false);

				if (((JButton) e.getSource()) == needReceiptButton_Yes)
				{
					if (!pumpLogic.printReceipt())
					{
						setToReceiptFailedScreen();
					}
					waitWhileThenSetToWelcomScreen();
				}
				else
				{
					setToWelcomScreen();
				}
			}
		};

		needReceiptButton_Yes = new JButton("YES");
		needReceiptButton_Yes.setBounds(106, 140, 90, 37);
		needReceiptButton_Yes.setFont(largeFont);
		needReceiptButton_Yes.addActionListener(actionListener);
		contentPane.add(needReceiptButton_Yes);

		needReceiptButton_No = new JButton("NO");
		needReceiptButton_No.setBounds(206, 140, 93, 37);
		needReceiptButton_No.setFont(largeFont);
		needReceiptButton_No.addActionListener(actionListener);
		contentPane.add(needReceiptButton_No);

		setNeedReceiptButtonsVisible(false);
	}

	private void setNeedReceiptButtonsVisible(boolean visible)
	{
		needReceiptButton_Yes.setVisible(visible);
		needReceiptButton_No.setVisible(visible);
	}

	private void initialRetryButton()
	{
		retryButton = new JButton("Press here to try again");
		retryButton.setBounds(70, 162, 254, 23);
		contentPane.add(retryButton);
		retryButton.setVisible(false);
		retryButton.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent e)
			{
				setToWelcomScreen();
			}
		});
	}

	private void initialLabels()
	{
		labelOne = new JLabel();
		smallFont = labelOne.getFont();
		labelOne.setBounds(70, 59, 354, 21);
		contentPane.add(labelOne);

		labelTwo = new JLabel();
		labelTwo.setBounds(70, 84, 354, 21);
		contentPane.add(labelTwo);

		labelThree = new JLabel();
		labelThree.setBounds(70, 109, 354, 21);
		contentPane.add(labelThree);

		//		assistanceLabel = new JLabel();
		//		assistanceLabel.setBounds(70, 220, 314, 32);
		//		contentPane.add(assistanceLabel);
	}

	private void initialCallForAssistanceButton()
	{
		callForAssistanceButton = new JButton(
				"<html>Call<br>operator<br>for<br>assistance</html>");
		callForAssistanceButton.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				callAssistance();
			}
		});
		callForAssistanceButton.setBounds(334, 162, 90, 90);
		contentPane.add(callForAssistanceButton);
	}

	private void callAssistance()
	{
		pumpLogic.callForAssistance();

		contentPane.invalidate();

		labelOne.setText("Operator has been alerted ");
		labelOne.setFont(smallFont);
		labelTwo.setText("and will be with you shortly. ");
		labelTwo.setFont(smallFont);
		labelThree.setText("");

		callForAssistanceButton.setVisible(false);
		setGradeButtonsVisible(false);
		retryButton.setVisible(false);

		contentPane.validate();

		waitWhileThenSetToWelcomScreen();

	}

	private void waitWhileThenSetToWelcomScreen()
	{
		new Thread()
		{
			public void run()
			{
				try
				{
					Thread.sleep(5000);
				}
				catch (InterruptedException e)
				{
				}

				setToWelcomScreen();
			}
		}.start();
	}

	public void setToWelcomScreen()
	{
		contentPane.invalidate();

		labelOne.setText("Welcome to UIC Gas");
		labelOne.setFont(largeFont);
		labelTwo.setText("Swipe your card at any time, or prepay inside");
		labelTwo.setFont(smallFont);
		labelThree.setText("");
		labelThree.setFont(smallFont);
		//		assistanceLabel.setText("");

		callForAssistanceButton.setVisible(true);
		retryButton.setVisible(false);
		setGradeButtonsVisible(false);
		RegularGradeRadioButton.setSelected(true);

		contentPane.validate();
	}

	public void setToValidatingCardScreen()
	{
		contentPane.invalidate();

		labelOne.setText("Please wait while ");
		labelOne.setFont(smallFont);
		labelTwo.setText("We process your card ");
		labelTwo.setFont(smallFont);
		labelThree.setText(". . . . . .");
		labelThree.setFont(smallFont);
		//		assistanceLabel.setText("");

		callForAssistanceButton.setVisible(true);

		contentPane.validate();
	}

	public void setToInValidateCardScreen()
	{
		contentPane.invalidate();

		labelOne.setText("Sorry, ");
		labelOne.setFont(largeFont);
		labelTwo.setText("card could not be approved. ");
		labelTwo.setFont(smallFont);
		labelThree.setText("");

		callForAssistanceButton.setVisible(true);
		retryButton.setVisible(true);

		contentPane.validate();
	}

	// Let user select grade
	private void setToReadyForPumpingGasScreen()
	{
		contentPane.invalidate();

		if (pumpLogic.getCurrentTransaction().getCreditCardInfo() != null)
		{
			labelOne.setText("Card Approved ");
		}
		else
		{
			labelOne.setText("Pump Activated ");
		}
		labelOne.setFont(largeFont);
		labelTwo.setText("Left nozzle ");
		labelTwo.setFont(smallFont);
		labelThree.setText("and select grade ");
		labelThree.setFont(smallFont);
		//		assistanceLabel.setText("");

		callForAssistanceButton.setVisible(true);
		retryButton.setVisible(false);

		setGradeButtonsVisible(true);

		contentPane.validate();
	}

	private void setGradeButtonsVisible(boolean visible)
	{
		RegularGradeRadioButton.setVisible(visible);
		midGradeRadioButton.setVisible(visible);
		premiumGradeRadioButton.setVisible(visible);
	}

	private void setToPumpingGasScreen(GasolineGrade grade,
			double currentGasAmount, double currentMoneyAmount)
	{
		contentPane.invalidate();

		callForAssistanceButton.setVisible(false);
		setGradeButtonsVisible(false);

		labelOne.setFont(smallFont);
		labelOne.setText(grade + " grade: $" + grade.getPrice());
		labelTwo.setText("Pumped: " + currentGasAmount + " Galloons");
		labelThree.setText("Amount: $" + currentMoneyAmount);

		contentPane.validate();
	}

	private void setToFinishedPumpingScreen(GasolineGrade grade,
			double currentGasAmount, double currentMoneyAmount)
	{
		contentPane.invalidate();

		callForAssistanceButton.setVisible(false);
		setGradeButtonsVisible(false);

		labelOne.setText("Would you like a receipt? ");
		labelOne.setFont(largeFont);
		labelTwo.setText("Pumped: " + currentGasAmount + " Galloons");
		labelThree.setText("Amount: $" + currentMoneyAmount);

		setNeedReceiptButtonsVisible(true);

		contentPane.validate();
	}

	private void setToReceiptFailedScreen()
	{
		contentPane.invalidate();

		labelOne.setText("Cannot print receipt at this time. ");
		labelOne.setFont(smallFont);
		labelTwo.setText("Please see operator at register for receipt. ");
		labelTwo.setFont(smallFont);
		labelThree.setText("");

		contentPane.validate();
	}

	public void setToOutOfServiceScreen()
	{
		contentPane.invalidate();

		labelOne.setText("This pump is ");
		labelOne.setFont(largeFont);
		labelTwo.setText("Out of Service ");
		labelTwo.setFont(largeFont);
		labelThree.setText("");

		callForAssistanceButton.setVisible(false);

		contentPane.validate();
	}

	@Override
	public void readyForPumping()
	{
		setToReadyForPumpingGasScreen();
	}

	@Override
	public void ammountChanged(GasolineGrade grade, double currentGasAmount,
			double currentMoneyAmount)
	{
		setToPumpingGasScreen(grade, currentGasAmount, currentMoneyAmount);
	}

	@Override
	public void finishedPumping(GasolineGrade grade, double currentGasAmount,
			double currentMoneyAmount)
	{
		setToFinishedPumpingScreen(grade, currentGasAmount, currentMoneyAmount);
		RegularGradeRadioButton.doClick();
	}

	//	@Override
	//	public void stoppedPumping(GasolineGrade grade, double currentGasAmount,
	//			double currentMoneyAmount)
	//	{
	//		callForAssistanceButton.setVisible(true);
	//
	//		// TODO Auto-generated method stub
	//		System.out.println("stoppedPumping: " + currentGasAmount + " "
	//				+ currentMoneyAmount);
	//	}

}
